package com.zhijian.wharf.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.zhijian.util.AssertUtil;
import com.zhijian.util.EncryptUtil;
import com.zhijian.util.page.Page;
import com.zhijian.wharf.dao.UserMapper;
import com.zhijian.wharf.entity.po.User;
import com.zhijian.wharf.entity.po.UserGroup;
import com.zhijian.wharf.entity.po.UserRole;
import com.zhijian.wharf.entity.vo.request.RoleSearchVo;
import com.zhijian.wharf.entity.vo.request.UserSaveOrUpdateVo;
import com.zhijian.wharf.entity.vo.request.UserSearchVo;
import com.zhijian.wharf.entity.vo.response.RoleVo;
import com.zhijian.wharf.entity.vo.response.UserVo;
import com.zhijian.wharf.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 人员业务处理层
 *
 * @author HCG
 * @date 2022-01-01 15:41:25
 * @version: 1.0
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper mapper;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserGroupService userGroupService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private OfficeGroupService officeGroupService;

    /**
     * 默认登录密码
     */
    @Value("${default.password}")
    private String defaultPassword;

    @Override
    public User selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public User selectByUserName(String userName) {
        return mapper.selectByUserName(userName);
    }

    @Override
    public User selectByUnionid(String unionid) {
        return mapper.selectByUnionid(unionid);
    }

    @Override
    public UserVo selectVoById(Long id) {
        UserVo userVo = mapper.selectVoById(id);
        if (Objects.nonNull(userVo)) {
            setRoleInfo(userVo);
            //角色id数组
            List<Long> roleIds = userRoleService.selectRoleIdListByUserId(id);
            userVo.setRoleIds(roleIds);
        }
        return userVo;
    }

    /**
     * 设置角色相关信息
     *
     * @param userVo
     */
    private void setRoleInfo(UserVo userVo) {
        //角色id数组
        List<Long> roleIds = userRoleService.selectRoleIdListByUserId(userVo.getId());
        userVo.setRoleIds(roleIds);
        List<RoleVo> roleVos = roleService.selectList(RoleSearchVo.builder()
                .idList(roleIds)
                .build());
        if (CollectionUtil.isNotEmpty(roleVos)) {
            userVo.setRoleNames(String.join(",", roleVos.stream().map(RoleVo::getName).collect(Collectors.toList())));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
        userRoleService.deleteByUserId(id);
        userGroupService.deleteByUserId(id);
    }

    @Override
    public boolean update(User user) {
        Date now = new Date();
        user.setUpdateTime(now);
        return mapper.updateByPrimaryKey(user) != 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean update(UserSaveOrUpdateVo userSaveOrUpdateVo) {
        Long userId = userSaveOrUpdateVo.getId();
        User user = this.selectById(userId);
        AssertUtil.notNull(user, "此用户不存在或者已被删除");
        Integer count = this.count(UserSearchVo.builder()
                .notId(userId)
                .phone(userSaveOrUpdateVo.getPhone())
                .build());
        AssertUtil.check(count > 0, "此手机号已存在");

        user.setName(userSaveOrUpdateVo.getName());
        user.setNickName(userSaveOrUpdateVo.getNickName());
        user.setPhone(userSaveOrUpdateVo.getPhone());
        user.setJobNumber(userSaveOrUpdateVo.getJobNumber());
        user.setNote(userSaveOrUpdateVo.getNote());
        user.setEmail(userSaveOrUpdateVo.getEmail());
        user.setStatus(userSaveOrUpdateVo.getStatus());
        this.update(user);


        //删除人-部门关系表
        userGroupService.deleteByUserId(userId);
        //插入人员-组织关系表
        userGroupService.insert(UserGroup.builder()
                .userId(userId)
                .groupId(userSaveOrUpdateVo.getGroupId())
                .build());

        //删除角色-人员关系表
        userRoleService.deleteByUserId(userId);
        List<Long> roleIds = userSaveOrUpdateVo.getRoleIds();
        roleIds.forEach(roleId -> userRoleService.insert(UserRole.builder()
                .userId(userId)
                .roleId(roleId)
                .build()));
        return true;
    }

    @Override
    public boolean updateByPrimaryKeySelective(User record) {
        return mapper.updateByPrimaryKeySelective(record) > 0;
    }

    @Override
    public Integer count(UserSearchVo userSearchVo) {
        return mapper.count(userSearchVo);
    }

    @Override
    public List<UserVo> selectList(UserSearchVo userSearchVo) {
        List<UserVo> userVoList = mapper.selectList(userSearchVo);
        if (CollectionUtil.isEmpty(userVoList)) {
            return Collections.emptyList();
        }
        userVoList.forEach(this::setRoleInfo);
        return userVoList;
    }

    @Override
    public Page<UserVo> selectPage(UserSearchVo userSearchVo) {
        //先直接查总数
        int count = count(userSearchVo);
        //分页
        Page<UserVo> page = new Page<>(true, count, userSearchVo.getPageNum(), userSearchVo.getPageSize());
        userSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<UserVo> responseVos = this.selectList(userSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public User selectByJobNumberAndPassword(String jobNumber, String password) {
        return mapper.selectByJobNumberAndPassword(jobNumber, password);
    }

    @Override
    public User selectByPhoneAndPassword(String phone, String password) {
        return mapper.selectByPhoneAndPassword(phone, password);
    }

    @Override
    public User selectByPhone(String phone) {
        return mapper.selectByPhone(phone);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long insert(UserSaveOrUpdateVo userSaveOrUpdateVo) {
        Integer count = this.count(UserSearchVo.builder()
                .phone(userSaveOrUpdateVo.getPhone())
                .build());
        AssertUtil.check(count > 0, "此手机号已存在");

        String salt = EncryptUtil.salt();
        //密码加盐，形成最后真正的密码
        String finalPwd = EncryptUtil.password(StringUtils.isBlank(userSaveOrUpdateVo.getPassword())
                ? defaultPassword : userSaveOrUpdateVo.getPassword(), salt);
        Date now = new Date();
        User user = User.builder()
                .name(userSaveOrUpdateVo.getName())
                .nickName(userSaveOrUpdateVo.getNickName())
                .phone(userSaveOrUpdateVo.getPhone())
                .jobNumber(userSaveOrUpdateVo.getJobNumber())
                .note(userSaveOrUpdateVo.getNote())
                .status(userSaveOrUpdateVo.getStatus())
                .password(finalPwd)
                .salt(salt)
                .email(userSaveOrUpdateVo.getEmail())
                .createTime(now)
                .updateTime(now)
                .build();
        Long userId = mapper.insert(user) > 0 ? user.getId() : 0L;
        AssertUtil.check(userId == 0, "保存失败");
        List<Long> roleIds = userSaveOrUpdateVo.getRoleIds();
        roleIds.forEach(roleId -> userRoleService.insert(UserRole.builder()
                .userId(userId)
                .roleId(roleId)
                .build()));
        //插入人员-组织关系表
        userGroupService.insert(UserGroup.builder()
                .userId(userId)
                .groupId(userSaveOrUpdateVo.getGroupId())
                .build());
        return userId;
    }

    @Override
    public UserVo selectVoByJobNumber(String jobNumber) {
        return mapper.selectVoByJobNumber(jobNumber);
    }

    @Override
    public List<UserVo> selectAllChildren(Long userId) {
//        //先找出这个用户的所有对应部门
//        List<Long> groupIds = userGroupService.selectGroupIdsByUserId(userId);
//        if (CollectionUtil.isEmpty(groupIds)) {
//            return Collections.emptyList();
//        }
//        List<Long> finalGroupIds = Lists.newLinkedList();
//        groupIds.forEach(groupId -> finalGroupIds.addAll(officeGroupService.concatIdsByParentId(groupId)));
//        //然后把所有部门id作为条件查询用户
//        return this.selectList(UserSearchVo.builder()
//                .groupIds(finalGroupIds)
//                .build());
        return null;
    }

    @Override
    public boolean uploadAvatar(Long id, MultipartFile file) {
//        UploadVo uploadVo = uploadService.upload(file);
//        return ObjectUtil.isNotNull(uploadVo) && this.updateByPrimaryKeySelective(User.builder()
//                .id(id)
//                .avatar(uploadVo.getUrlPath())
//                .build());
        return false;
    }

    @Override
    public boolean updateUserName(Long id, String userName) {
        Integer count = this.count(UserSearchVo.builder()
                .notId(id)
                .userName(userName)
                .build());
        AssertUtil.check(count > 0, "此用户名已存在");
        return this.updateByPrimaryKeySelective(User.builder()
                .id(id)
                .userName(userName)
                .build());
    }

    @Override
    public boolean updatePhone(Long id, String phone) {
        Integer count = this.count(UserSearchVo.builder()
                .notId(id)
                .phone(phone)
                .build());
        AssertUtil.check(count > 0, "此手机号码已存在");
        return this.updateByPrimaryKeySelective(User.builder()
                .id(id)
                .phone(phone)
                .build());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return;
        }
        mapper.deleteByIdList(idList);
    }

    @Override
    public boolean setNullMobileParamByOpenIdAndNotId(String openid, Long notId) {
        return mapper.setNullMobileParamByOpenIdAndNotId(openid, notId) != 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean register(String phone, String miniOpenId, String unionid, String publicOpenId) {
//        Integer count = this.count(UserSearchVo.builder()
//                .phone(phone)
//                .build());
//        AssertUtil.check(count > 0, "手机号已注册，请直接登录");
//        String salt = EncryptUtil.salt();
//        //密码加盐，形成最后真正的密码
//        String finalPwd = EncryptUtil.password(defaultPassword, salt);
//        Date now = new Date();
//        User user = User.builder()
//                .name(phone)
//                .nickName(phone)
//                .userName(phone)
//                .phone(phone)
//                .status(StatusEnum.NORMAL.getCode().byteValue())
//                .password(finalPwd)
//                .salt(salt)
//                .miniOpenid(miniOpenId)
//                .unionid(unionid)
//                .publicOpenid(publicOpenId)
//                .createTime(now)
//                .updateTime(now)
//                .build();
//        Long userId = mapper.insert(user) > 0 ? user.getId() : 0L;
//        AssertUtil.check(userId == 0, "保存失败");
//        //部门
//        OfficeGroup officeGroup = officeGroupService.selectByName(OfficeGroupEnum.REGISTER.getDesc());
//        AssertUtil.notNull(officeGroup, "部门初始化失败");
//        userGroupService.insert(UserGroup.builder()
//                .userId(userId)
//                .groupId(officeGroup.getId())
//                .build());
//        //角色
//        RoleVo roleVo = roleService.selectVoByName(RoleEnum.REGISTER.getDesc());
//        AssertUtil.notNull(roleVo, "角色初始化失败");
//        userRoleService.insert(UserRole.builder()
//                .userId(userId)
//                .roleId(roleVo.getId())
//                .build());
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean register(String phone, String miniOpenId, String unionid, String publicOpenId, String password) {
//        Integer count = this.count(UserSearchVo.builder()
//                .phone(phone)
//                .build());
//        AssertUtil.check(count > 0, "手机号已注册，请直接登录");
//        String salt = EncryptUtil.salt();
//        //密码加盐，形成最后真正的密码
//        String finalPwd = EncryptUtil.password(password, salt);
//        Date now = new Date();
//        User user = User.builder()
//                .name(phone)
//                .nickName(phone)
//                .userName(phone)
//                .phone(phone)
//                .status(StatusEnum.NORMAL.getCode().byteValue())
//                .password(finalPwd)
//                .salt(salt)
//                .miniOpenid(miniOpenId)
//                .unionid(unionid)
//                .publicOpenid(publicOpenId)
//                .createTime(now)
//                .updateTime(now)
//                .build();
//        Long userId = mapper.insert(user) > 0 ? user.getId() : 0L;
//        AssertUtil.check(userId == 0, "保存失败");
//        //部门
//        OfficeGroup officeGroup = officeGroupService.selectByName(OfficeGroupEnum.REGISTER.getDesc());
//        AssertUtil.notNull(officeGroup, "部门初始化失败");
//        userGroupService.insert(UserGroup.builder()
//                .userId(userId)
//                .groupId(officeGroup.getId())
//                .build());
//        //角色
//        RoleVo roleVo = roleService.selectVoByName(RoleEnum.REGISTER.getDesc());
//        AssertUtil.notNull(roleVo, "角色初始化失败");
//        userRoleService.insert(UserRole.builder()
//                .userId(userId)
//                .roleId(roleVo.getId())
//                .build());
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean register(String phone) {
//        Integer count = this.count(UserSearchVo.builder()
//                .phone(phone)
//                .build());
//        AssertUtil.check(count > 0, "手机号已注册，请直接登录");
//        String salt = EncryptUtil.salt();
//        //密码加盐，形成最后真正的密码
//        String finalPwd = EncryptUtil.password(defaultPassword, salt);
//        Date now = new Date();
//        User user = User.builder()
//                .name(phone)
//                .nickName(phone)
//                .userName(phone)
//                .phone(phone)
//                .status(StatusEnum.NORMAL.getCode().byteValue())
//                .password(finalPwd)
//                .salt(salt)
//                .createTime(now)
//                .updateTime(now)
//                .build();
//        Long userId = mapper.insert(user) > 0 ? user.getId() : 0L;
//        AssertUtil.check(userId == 0, "保存失败");
//        //部门
//        OfficeGroup officeGroup = officeGroupService.selectByName(OfficeGroupEnum.REGISTER.getDesc());
//        AssertUtil.notNull(officeGroup, "部门初始化失败");
//        userGroupService.insert(UserGroup.builder()
//                .userId(userId)
//                .groupId(officeGroup.getId())
//                .build());
//        //角色
//        RoleVo roleVo = roleService.selectVoByName(RoleEnum.REGISTER.getDesc());
//        AssertUtil.notNull(roleVo, "角色初始化失败");
//        userRoleService.insert(UserRole.builder()
//                .userId(userId)
//                .roleId(roleVo.getId())
//                .build());
        return true;
    }

}